import { LockOutlined, UserOutlined } from '@ant-design/icons';
import { Button, Checkbox, Input, Typography } from 'antd';
import aes from 'crypto-js/aes';
import uft8 from 'crypto-js/enc-utf8';
import React, { useEffect, useReducer, useRef } from 'react';
import useModal from '../components/useModal';
import alert from '../utils/alert';
import client from '../utils/client';
import { delCookie, getCookie, setCookie } from '../utils/cookie';
import styles from './login.module.css';

const COOKIE_EXPIRES = 315360000; // 十年的秒数
const AES_KEY = 'meta.one.platform';

function login_reducer(state, action) {
  switch (action.type) {
    case 'system': {
      return { ...state, title: action.title, logo: action.logo };
    }
    case 'user_change': {
      return { ...state, username: action.value };
    }
    case 'password_change': {
      return { ...state, password: action.value };
    }
    case 'remember_user_change': {
      if (!state.remember_user) {
        setCookie('remember_user', true, COOKIE_EXPIRES);
        return { ...state, remember_user: true };
      } else {
        delCookie('remember_user');
        return { ...state, remember_user: false };
      }
    }
    case 'login': {
      return { ...state, logging: true };
    }
    case 'done': {
      return { ...state, logging: false };
    }
    default: {
      return state;
    }
  }
}

function Login(props) {
  const ref_user = useRef(null);
  const ref_password = useRef(null);
  const [modal, modalHolder] = useModal();

  const [state, dispatch] = useReducer(login_reducer, {
    title: client.get('system')?.名称,
    logo: client.get('system')?.图标地址,
    logging: false,
    username: getCookie('username'),
    password: getCookie('password') ? aes.decrypt(getCookie('password'), AES_KEY).toString(uft8) : null,
    remember_user: getCookie('remember_user') === 'true',
  });

  // 挂载后设置焦点
  useEffect(() => {
    if (state.username) {
      ref_password.current.focus();
    } else {
      ref_user.current.focus();
    }
    // eslint-disable-next-line
  }, []);

  function commit() {
    if (!state.username) return;
    // 写入Cookie
    if (state.remember_user) {
      setCookie('username', state.username, COOKIE_EXPIRES);
    } else {
      delCookie('username');
    }

    dispatch({ type: 'login' });
    props.login(state.username, state.password)
      .catch(e => {
        if (e.message && e.message.includes('密码未设置')) {
          initPassword(state.username);
        } else {
          alert('错误', e.message, { type: 'error' });
        }
      })
      .then(() => dispatch({ type: 'done' }));
  }

  // 设置初始密码
  function initPassword(username) {
    let pwd1 = "";
    let pwd2 = "";
    modal.open({
      title: `请设置${username}账户的登录密码`,
      content: (
        <div style={{ padding: '10px 0' }}>
          <Input type="password" placeholder="请输入密码" style={{ margin: '4px 0' }}
            onChange={e => pwd1 = e.target.value} />
          <Input type="password" placeholder="请再次输入密码" style={{ margin: '4px 0' }}
            onChange={e => pwd2 = e.target.value} />
          <h5>长度不小于8, 至少包含大写字母, 小写字母, 数字和特殊字符中的三种</h5>
        </div>
      ),
      onOk: () => new Promise((resolve, reject) => {
        // 验证两次输入相同
        if (pwd1 !== pwd2) {
          alert('两次输入的密码不一致', null, { type: 'error' });
          return reject();
        }
        // 验证密码复杂度
        if (pwd1.length < 8 || complexity(pwd1) < 3) {
          alert('复杂度不足', '至少包含8个字符, 至少包含大写字母, 小写字母, 数字和特殊字符中的三种', { type: 'error' });
          return reject();
        }

        // 修改密码
        client.init_password(username, pwd1).then(() => {
          alert('操作成功', '设置成功。您可以登录系统了');
          resolve();
        }).catch(e => {
          reject();
          alert('错误', e.message, { type: 'error' });
        });
      })
    });
  }

  /**
   * 计算密码复杂度
   * @return {number}
   */
  function complexity(s) {
    let n = 0;
    if (s.match(/([a-z])+/)) n++;
    if (s.match(/([0-9])+/)) n++;
    if (s.match(/([A-Z])+/)) n++;
    if (s.match(/[^a-zA-Z0-9]+/)) n++;
    return n;
  }

  document.title = state.title + " - 登录页";

  return (
    <div className={styles.login}>
      <div className={styles.login_box}>
        <div className={styles.login_border}>
          <div className={styles.login_logo}>
            {!state.logo ? null : <img alt="logo" src={state.logo} />}
          </div>
          {!state.title ? null : <Typography.Title level={2}>{state.title}</Typography.Title>}
          <div className={styles.login_form}>
            <Input ref={ref_user} value={state.username} prefix={<UserOutlined style={{ color: 'rgba(0, 0, 0, 0.25)' }} />} size="large" placeholder="账户名"
              onChange={e => dispatch({ type: 'user_change', value: e.target.value })} onPressEnter={commit} />
            <Input ref={ref_password} value={state.password} prefix={<LockOutlined style={{ color: 'rgba(0, 0, 0, 0.25)' }} />} size="large" type="password" placeholder="密码"
              onChange={e => dispatch({ type: 'password_change', value: e.target.value })} onPressEnter={commit} />
            <Checkbox checked={state.remember_user} onChange={() => dispatch({ type: 'remember_user_change' })}>记住账户</Checkbox>
          </div>
          <Button type="primary" size="large" loading={state.logging} onClick={commit}>登录</Button>
        </div>
      </div>
      {modalHolder}
    </div>
  );
}

export default Login;